home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 701-725 / 708 / intuisup / intuisup42.lha / Intuisup / source.lha / Editor / load.c < prev    next >
C/C++ Source or Header  |  1992-03-21  |  18KB  |  720 lines

  1. /* $Revision Header *** Header built automatically - do not edit! ***********
  2.  *
  3.  *    (C) Copyright 1991 by Torsten Jürgeleit
  4.  *
  5.  *    Name .....: load.c
  6.  *    Created ..: Sunday 22-Dec-91 21:22:44
  7.  *    Revision .: 1
  8.  *
  9.  *    Date        Author                 Comment
  10.  *    =========   ====================   ====================
  11.  *    31-Dec-91   Torsten Jürgeleit      new font management
  12.  *    22-Dec-91   Torsten Jürgeleit      Created this file!
  13.  *
  14.  ****************************************************************************
  15.  *
  16.  *    Load template files
  17.  *
  18.  * $Revision Header ********************************************************/
  19.  
  20.     /* Includes */
  21.  
  22. #include "includes.h"
  23. #include "defines.h"
  24. #include "imports.h"
  25. #include "protos.h"
  26.  
  27.     /* Defines */
  28.  
  29. #define LOAD_FILE_READ_BUFFER_SIZE    2000
  30. #define LOAD_FILE_LINE_BUFFER_SIZE    80
  31. #define LOAD_FILE_FLAGS            (TEXT_FILE_FLAG_TRIM_LINE | TEXT_FILE_FLAG_SKIP_COMMENTS | TEXT_FILE_FLAG_SKIP_EMPTY_LINES | TEXT_FILE_FLAG_LINE_CONTINUATION)
  32.  
  33. #define BLOCK_TYPE_NONE        0
  34. #define BLOCK_TYPE_HEADER    1
  35. #define BLOCK_TYPE_FONT        2
  36. #define BLOCK_TYPE_TEMPLATE    3
  37. #define BLOCK_TYPE_BOX        4
  38. #define BLOCK_TYPE_TEXTLIST    5
  39. #define BLOCK_TYPE_BORDERDATA    6
  40. #define BLOCK_TYPE_TEXTDATA    7
  41. #define BLOCK_TYPE_GADGETDATA    8
  42.  
  43. #define HEADER_ITEM_TYPE_LEFTEDGE    1
  44. #define HEADER_ITEM_TYPE_TOPEDGE    2
  45. #define HEADER_ITEM_TYPE_WIDTH        3
  46. #define HEADER_ITEM_TYPE_HEIGHT        4
  47. #define HEADER_ITEM_TYPE_FLAGS        5
  48. #define HEADER_ITEM_TYPE_ID        6
  49.  
  50. #define FONT_ITEM_TYPE_NAME        1
  51. #define FONT_ITEM_TYPE_YSIZE        2
  52.  
  53. #define TEMPLATE_ITEM_TYPE_NAME        1
  54. #define TEMPLATE_ITEM_TYPE_TYPE        2
  55. #define TEMPLATE_ITEM_TYPE_FLAGS    3
  56.  
  57. #define BOX_ITEM_TYPE_X1        1
  58. #define BOX_ITEM_TYPE_Y1        2
  59. #define BOX_ITEM_TYPE_X2        3
  60. #define BOX_ITEM_TYPE_Y2        4
  61.  
  62. #define TEXTLIST_ITEM_TYPE_TEXT        1
  63.  
  64. #define BORDERDATA_ITEM_TYPE_TYPE    1
  65.  
  66. #define TEXTDATA_ITEM_TYPE_TYPE        1
  67. #define TEXTDATA_ITEM_TYPE_FLAGS    2
  68. #define TEXTDATA_ITEM_TYPE_TEXT        3
  69. #define TEXTDATA_ITEM_TYPE_TEXTATTR    4
  70.  
  71. #define GADGETDATA_ITEM_TYPE_TYPE    1
  72. #define GADGETDATA_ITEM_TYPE_FLAGS    2
  73. #define GADGETDATA_ITEM_TYPE_TEXT    3
  74. #define GADGETDATA_ITEM_TYPE_TEXTATTR    4
  75. #define GADGETDATA_ITEM_TYPE_SPECIAL1    5
  76. #define GADGETDATA_ITEM_TYPE_SPECIAL2    6
  77. #define GADGETDATA_ITEM_TYPE_SPECIAL3    7
  78.  
  79.     /* Statics */
  80.  
  81. STATIC struct TemplateList  new_template_list;
  82. STATIC struct TemplateFont  *new_font;
  83. STATIC struct Template      *new_template;
  84.  
  85. STATIC BYTE *block_keywords[] = {
  86.     "PROJECTHEADER",
  87.     "FONT",
  88.     "TEMPLATE",
  89.     "BOX",
  90.     "TEXTLIST",
  91.     "BORDERDATA",
  92.     "TEXTDATA",
  93.     "GADGETDATA",
  94.     NULL
  95. };
  96. STATIC BYTE *header_keywords[] = {
  97.     "LEFTEDGE",
  98.     "TOPEDGE",
  99.     "WIDTH",
  100.     "HEIGHT",
  101.     "FLAGS",
  102.     "ID",
  103.     NULL
  104. };
  105. STATIC BYTE *font_keywords[] = {
  106.     "NAME",
  107.     "YSIZE",
  108.     NULL
  109. };
  110. STATIC BYTE *template_keywords[] = {
  111.     "NAME",
  112.     "TYPE",
  113.     "FLAGS",
  114.     NULL
  115. };
  116. STATIC BYTE *box_keywords[] = {
  117.     "X1",
  118.     "Y1",
  119.     "X2",
  120.     "Y2",
  121.     NULL
  122. };
  123. STATIC BYTE *textlist_keywords[] = {
  124.     "TEXT",
  125.     NULL
  126. };
  127. STATIC BYTE *borderdata_keywords[] = {
  128.     "TYPE",
  129.     NULL
  130. };
  131. STATIC BYTE *textdata_keywords[] = {
  132.     "TYPE",
  133.     "FLAGS",
  134.     "TEXT",
  135.     "TEXTATTR",
  136.     NULL
  137. };
  138. STATIC BYTE *gadgetdata_keywords[] = {
  139.     "TYPE",
  140.     "FLAGS",
  141.     "TEXT",
  142.     "TEXTATTR",
  143.     "SPECIAL1",
  144.     "SPECIAL2",
  145.     "SPECIAL3",
  146.     NULL
  147. };
  148.     /* Load project */
  149.  
  150.    SHORT
  151. load_project(USHORT mode)
  152. {
  153.    struct FileRequester  *freq = project_file_requester;
  154.    SHORT status = EDITOR_STATUS_NORMAL;
  155.  
  156.    /* Display ARP file requester and check if user selected cancel */
  157.    IChangeMousePointer(ewin, NULL);
  158.    freq->fr_FuncFlags &= ~FRF_DoColor;
  159.    if (mode == LOAD_MODE_NORMAL) {
  160.       freq->fr_Hail = PROJECT_LOAD_HAIL_TEXT;
  161.    } else {
  162.       freq->fr_Hail = PROJECT_APPEND_HAIL_TEXT;
  163.    }
  164.    if (FileRequest(freq)) {
  165.       struct TemplateList  *new_tl = &new_template_list;
  166.       struct FileData      *fd;
  167.       BYTE  path[LONG_DSIZE + LONG_FSIZE + 1];
  168.       SHORT len = strlen(freq->fr_File) - 4;
  169.  
  170.       /* Prepare file name and project name */
  171.       if (len < 1 || Strcmp(freq->fr_File + len, ".tpl")) {
  172.      strcat(freq->fr_File, ".tpl");
  173.      len += 4;
  174.       }
  175.  
  176.       /* Build full path for project file */
  177.       strcpy(&path[0], freq->fr_Dir);
  178.       TackOn(&path[0], freq->fr_File);
  179.  
  180.       /* Open file */
  181.       if (!(fd = IOpenTextFile(&path[0], LOAD_FILE_READ_BUFFER_SIZE,
  182.                 LOAD_FILE_LINE_BUFFER_SIZE, LOAD_FILE_FLAGS))) {
  183.      status = EDITOR_ERROR_OPEN_FAILED;
  184.       } else {
  185.  
  186.      /* Init new template list */
  187.      NewList((struct List *)&new_tl->tl_Fonts);
  188.      NewList((struct List *)&new_tl->tl_Templates);
  189.      new_tl->tl_BorderTemplates = 0;
  190.      new_tl->tl_TextTemplates   = 0;
  191.      new_tl->tl_GadgetTemplates = 0;
  192.      new_tl->tl_Flags           = DEFAULT_TEMPLATE_LIST_FLAGS;
  193.  
  194.      /* Read all templates */
  195.      while ((status = parse_block(fd, new_tl, BLOCK_TYPE_NONE,
  196.                         mode)) == EDITOR_STATUS_NORMAL);
  197.      /* Install and display new template list */
  198.      if (status == EDITOR_STATUS_EOF) {
  199.         struct TemplateList  *tl = &template_list;
  200.         struct TemplateFont  *tf;
  201.         struct Template      *tp;
  202.         struct List          *list;
  203.  
  204.         /* First set normal status */
  205.         status = EDITOR_STATUS_NORMAL;
  206.  
  207.         /* Remove unused template fonts from new template list */
  208.         tf = get_head((struct List *)&new_tl->tl_Fonts);
  209.         while (tf) {
  210.            struct TemplateFont  *next_tf = get_succ((struct Node *)
  211.                                &tf->tf_MinNode);
  212.            if (!tf->tf_UseCount) {
  213.           Remove((struct Node *)&tf->tf_MinNode);
  214.           free_template_font(tf);
  215.            }
  216.            tf = next_tf;
  217.         }
  218.         if (mode == LOAD_MODE_NORMAL) {
  219.  
  220.            /* Overwrite old template list */
  221.            if ((status = new_project(tl, new_tl->tl_Flags)) ==
  222.                              EDITOR_STATUS_NORMAL) {
  223.           /* Copy template fonts from new to original template list */
  224.           list = (struct List *)&new_tl->tl_Fonts;
  225.           while (tf = (struct TemplateFont *)RemHead(list)) {
  226.              AddTail((struct List *)&tl->tl_Fonts,
  227.                         (struct Node *)&tf->tf_MinNode);
  228.           }
  229.  
  230.           /* Copy templates from new to original template list */
  231.           list = (struct List *)&new_tl->tl_Templates;
  232.           while (tp = (struct Template *)RemHead(list)) {
  233.              add_template_to_list(tl, tp, FALSE);
  234.              display_template(tp);
  235.           }
  236.  
  237.           /* Copy template list data */
  238.           tl->tl_Flags = new_tl->tl_Flags &
  239.                         ~TEMPLATE_LIST_FLAG_CHANGED;
  240.           strcpy(&tl->tl_ProjectID[0], &new_tl->tl_ProjectID[0]);
  241.           change_project_name(tl, freq->fr_File, len);
  242.            }
  243.         } else {
  244.  
  245.            /* Append new template list to old one */
  246.            list = (struct List *)&new_tl->tl_Templates;
  247.            while (tp = (struct Template *)RemHead(list)) {
  248.           struct TextAttr  *old_ta, *new_ta;
  249.  
  250.           /* Open template font in original template list and close it in new one */
  251.           switch (TEMPLATE_GROUP(tp)) {
  252.              case TEMPLATE_GROUP_TEXT :
  253.             old_ta = tp->tp_Data.tp_TextData.td_TextAttr;
  254.             if (!(new_ta = open_template_font_by_attributes(tl,
  255.                   (BYTE *)old_ta->ta_Name, old_ta->ta_YSize))) {
  256.                status = EDITOR_ERROR_INVALID_FONT;
  257.             } else {
  258.                tp->tp_Data.tp_TextData.td_TextAttr = new_ta;
  259.                close_template_font(new_tl, old_ta);
  260.             }
  261.             break;
  262.  
  263.              case TEMPLATE_GROUP_GADGET :
  264.             old_ta = tp->tp_Data.tp_GadgetData.gd_TextAttr;
  265.             if (!(new_ta = open_template_font_by_attributes(tl,
  266.                   (BYTE *)old_ta->ta_Name, old_ta->ta_YSize))) {
  267.                status = EDITOR_ERROR_INVALID_FONT;
  268.             } else {
  269.                tp->tp_Data.tp_GadgetData.gd_TextAttr = new_ta;
  270.                close_template_font(new_tl, old_ta);
  271.             }
  272.             break;
  273.           }
  274.  
  275.           if (status != EDITOR_STATUS_NORMAL) {
  276.              free_template(new_tl, tp);
  277.           } else {
  278.  
  279.              /* Add template to original template list */
  280.              if (tp->tp_Flags & TEMPLATE_FLAG_DEFAULT_NAME) {
  281.             add_template_to_list(tl, tp, TRUE);
  282.              } else {
  283.             add_template_to_list(tl, tp, FALSE);
  284.              }
  285.              display_template(tp);
  286.              tl->tl_Flags |= TEMPLATE_LIST_FLAG_CHANGED;
  287.           }
  288.                   }
  289.         }
  290.         if (status == EDITOR_STATUS_NORMAL) {
  291.            ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L, 0L,
  292.            USE_CURRENT_VALUE, USE_CURRENT_VALUE, &tl->tl_Templates);
  293.         }
  294.      }
  295.      ICloseTextFile(fd);
  296.  
  297.      /* If error then free incomplete loaded template list */
  298.      if (status != EDITOR_STATUS_NORMAL) {
  299.         free_template_list(new_tl);
  300.      }
  301.       }
  302.    }
  303.    IRestoreMousePointer(ewin);
  304.    if (status != EDITOR_STATUS_NORMAL) {
  305.       show_error(status);
  306.    }
  307.    return(status);
  308. }
  309.     /* Parse block of load file */
  310.  
  311.    STATIC SHORT
  312. parse_block(struct FileData  *fd, struct TemplateList  *tl,
  313.                          USHORT block_type, USHORT mode)
  314. {
  315.    SHORT status = EDITOR_STATUS_NORMAL;
  316.  
  317.    if (block_type == BLOCK_TYPE_FONT) {
  318.       struct TemplateFont  *tf;
  319.  
  320.       if (!(tf = new_font = AllocMem((LONG)sizeof(struct TemplateFont),
  321.                      (LONG)MEMF_PUBLIC | MEMF_CLEAR))) {
  322.      status = EDITOR_ERROR_OUT_OF_MEM;
  323.       } else {
  324.      struct TextAttr  *ta = &tf->tf_TextAttr;
  325.  
  326.      /* Init new template font */
  327.      ta->ta_Style    = FS_NORMAL;
  328.      ta->ta_Flags    = FPF_ROMFONT;
  329.      tf->tf_UseCount = 0;
  330.       }
  331.    } else {
  332.       if (block_type == BLOCK_TYPE_TEMPLATE) {
  333.      struct Template  *tp;
  334.  
  335.      if (!(tp = new_template = AllocMem((LONG)sizeof(struct Template),
  336.                      (LONG)MEMF_PUBLIC | MEMF_CLEAR))) {
  337.         status = EDITOR_ERROR_OUT_OF_MEM;
  338.      } else {
  339.  
  340.         /* Init new template */
  341.         NewList(&tp->tp_TextList);
  342.         tp->tp_Node.ln_Name = &tp->tp_TemplateName[0];
  343.      }
  344.       }
  345.    }
  346.    if (status == EDITOR_STATUS_NORMAL) {
  347.  
  348.       /* Block loop */
  349.       do {
  350.      BYTE c, *keyword, *arg;
  351.  
  352.      switch (IReadTextLine(fd)) {
  353.         case TEXT_FILE_STATUS_NORMAL :
  354.  
  355.            /* Mark end of keyword */
  356.            keyword = arg = fd->fd_Line;
  357.            while ((c = *arg++) != ' ' && c != '=' && c != '\0');
  358.            if (c == '\0') {
  359.           status = EDITOR_ERROR_NO_ARGUMENT;
  360.            } else {
  361.           *(arg - 1) = '\0';
  362.  
  363.           /* Strip double quotes from string argument */
  364.           if (*arg == '"') {
  365.              arg++;
  366.              *(arg + (strlen(arg) - 1)) = '\0';
  367.           }
  368.  
  369.               /* Check keyword */
  370.               if (!Strcmp(keyword, "BEGIN")) {
  371.  
  372.              /* Begin new block */
  373.              status = parse_block(fd, tl, search_keyword(arg,
  374.                          &block_keywords[0]), mode);
  375.           } else {
  376.              if (!Strcmp(keyword, "END")) {
  377.  
  378.             /* End current block */
  379.             if (search_keyword(arg, &block_keywords[0]) !=
  380.                                    block_type) {
  381.                status = EDITOR_ERROR_END_WRONG_BLOCK;
  382.             } else {
  383.                status = EDITOR_STATUS_EOB;
  384.             }
  385.              } else {
  386.  
  387.             /* Parse item */
  388.             status = parse_item(tl, block_type, keyword, arg,
  389.                                       mode);
  390.              }
  391.           }
  392.            }
  393.            break;
  394.  
  395.         case TEXT_FILE_STATUS_EOF :
  396.            status = EDITOR_STATUS_EOF;
  397.            break;
  398.  
  399.         case TEXT_FILE_ERROR_LINE_TOO_LONG :
  400.            status = EDITOR_ERROR_LINE_TOO_LONG;
  401.            break;
  402.  
  403.         default :
  404.            status = EDITOR_ERROR_READ_FAILED;
  405.            break;
  406.      }
  407.       } while (status == EDITOR_STATUS_NORMAL);
  408.       if (status != EDITOR_STATUS_EOB) {
  409.  
  410.      /* Free incomplete block */
  411.      switch (block_type) {
  412.         case BLOCK_TYPE_FONT :
  413.            free_template_font(new_font);
  414.            break;
  415.  
  416.         case BLOCK_TYPE_TEMPLATE :
  417.            free_template(tl, new_template);
  418.            break;
  419.  
  420.         case BLOCK_TYPE_TEXTLIST :
  421.            free_template_text_list(new_template);
  422.            break;
  423.      }
  424.       } else {
  425.      if (block_type == BLOCK_TYPE_FONT) {
  426.         AddTail((struct List *)&tl->tl_Fonts,
  427.                       (struct Node *)&new_font->tf_MinNode);
  428.      } else {
  429.         if (block_type == BLOCK_TYPE_TEMPLATE) {
  430.            struct Template      *tp;
  431.            struct Box           *box;
  432.            struct BorderData    *bd;
  433.            struct TextData      *td;
  434.            struct GadgetData    *gd;
  435.  
  436.            /* Init new template */
  437.            tp  = new_template;
  438.            box = &tp->tp_Box;
  439.            tp->tp_Node.ln_Name = &tp->tp_TemplateName[0];
  440.            switch (TEMPLATE_GROUP(tp)) {
  441.           case TEMPLATE_GROUP_BORDER :
  442.  
  443.              /* Init border template */
  444.              bd                = &tp->tp_Data.tp_BorderData;
  445.              bd->bd_LeftEdge   = box->bo_X1;
  446.              bd->bd_TopEdge    = box->bo_Y1;
  447.              bd->bd_Width      = box->bo_X2 - box->bo_X1 + 1;
  448.              bd->bd_Height     = box->bo_Y2 - box->bo_Y1 + 1;
  449.              (bd + 1)->bd_Type = INTUISUP_DATA_END;
  450.              break;
  451.  
  452.           case TEMPLATE_GROUP_TEXT :
  453.  
  454.              /* Init text template */
  455.              td                = &tp->tp_Data.tp_TextData;
  456.              td->td_LeftEdge   = box->bo_X1;
  457.              td->td_TopEdge    = box->bo_Y1;
  458.              (td + 1)->td_Type = INTUISUP_DATA_END;
  459.              break;
  460.  
  461.           case TEMPLATE_GROUP_GADGET :
  462.  
  463.              /* Init gadget template */
  464.              gd                = &tp->tp_Data.tp_GadgetData;
  465.              gd->gd_LeftEdge   = box->bo_X1;
  466.              gd->gd_TopEdge    = box->bo_Y1;
  467.              gd->gd_Width      = box->bo_X2 - box->bo_X1 + 1;
  468.              gd->gd_Height     = box->bo_Y2 - box->bo_Y1 + 1;
  469.              (gd + 1)->gd_Type = INTUISUP_DATA_END;
  470.              break;
  471.            }
  472.            add_template_to_list(tl, tp, FALSE);
  473.         }
  474.      }
  475.      status = EDITOR_STATUS_NORMAL;
  476.       }
  477.    }
  478.    return(status);
  479. }
  480.     /* Parse block of load file */
  481.  
  482.    STATIC SHORT
  483. parse_item(struct TemplateList  *tl, USHORT block_type, BYTE *keyword,
  484.                              BYTE *arg, USHORT mode)
  485. {
  486.    struct TextAttr    *ta;
  487.    struct Template    *tp;
  488.    struct Box         *box;
  489.    struct BorderData  *bd;
  490.    struct TextData    *td;
  491.    struct GadgetData  *gd;
  492.    SHORT status = EDITOR_STATUS_NORMAL;
  493.  
  494.    switch (block_type) {
  495.       case BLOCK_TYPE_HEADER :
  496.  
  497.      /* Read header data */
  498.      if (mode == LOAD_MODE_NORMAL) {
  499.         struct NewWindow  *nwin = &project_new_window;
  500.  
  501.         switch (search_keyword(keyword, &header_keywords[0])) {
  502.            case HEADER_ITEM_TYPE_LEFTEDGE :
  503.           nwin->LeftEdge = Atol(arg);
  504.           break;
  505.  
  506.            case HEADER_ITEM_TYPE_TOPEDGE :
  507.           nwin->TopEdge = Atol(arg);
  508.           break;
  509.  
  510.            case HEADER_ITEM_TYPE_WIDTH :
  511.           nwin->Width = Atol(arg);
  512.           break;
  513.  
  514.            case HEADER_ITEM_TYPE_HEIGHT :
  515.           nwin->Height = Atol(arg);
  516.           break;
  517.  
  518.            case HEADER_ITEM_TYPE_FLAGS :
  519.           tl->tl_Flags = Atol(arg);
  520.           break;
  521.  
  522.            case HEADER_ITEM_TYPE_ID :
  523.           strcpy(&tl->tl_ProjectID[0], arg);
  524.           break;
  525.         }
  526.      }
  527.      break;
  528.  
  529.       case BLOCK_TYPE_FONT :
  530.  
  531.      /* Read template font data */
  532.      ta = &new_font->tf_TextAttr;
  533.      switch (search_keyword(keyword, &font_keywords[0])) {
  534.         case FONT_ITEM_TYPE_NAME :
  535.            status = duplicate_string(arg, (BYTE **)&ta->ta_Name);
  536.            break;
  537.  
  538.         case FONT_ITEM_TYPE_YSIZE :
  539.            ta->ta_YSize = Atol(arg);
  540.            break;
  541.      }
  542.      break;
  543.  
  544.       case BLOCK_TYPE_TEMPLATE :
  545.  
  546.      /* Read template data */
  547.      tp = new_template;
  548.      switch (search_keyword(keyword, &template_keywords[0])) {
  549.         case TEMPLATE_ITEM_TYPE_NAME :
  550.            strcpy(&tp->tp_TemplateName[0], arg);
  551.            break;
  552.  
  553.         case TEMPLATE_ITEM_TYPE_TYPE :
  554.            tp->tp_Type = Atol(arg);
  555.            break;
  556.  
  557.         case TEMPLATE_ITEM_TYPE_FLAGS :
  558.            tp->tp_Flags = Atol(arg);
  559.            break;
  560.      }
  561.      break;
  562.  
  563.       case BLOCK_TYPE_BOX :
  564.      
  565.      /* Read box data */
  566.      box = &new_template->tp_Box;
  567.      switch (search_keyword(keyword, &box_keywords[0])) {
  568.         case BOX_ITEM_TYPE_X1 :
  569.            box->bo_X1 = Atol(arg);
  570.            break;
  571.  
  572.         case BOX_ITEM_TYPE_Y1 :
  573.            box->bo_Y1 = Atol(arg);
  574.            break;
  575.  
  576.         case BOX_ITEM_TYPE_X2 :
  577.            box->bo_X2 = Atol(arg);
  578.            break;
  579.  
  580.         case BOX_ITEM_TYPE_Y2 :
  581.            box->bo_Y2 = Atol(arg);
  582.            break;
  583.      }
  584.      break;
  585.  
  586.       case BLOCK_TYPE_TEXTLIST :
  587.  
  588.      /* Read text list */
  589.      switch (search_keyword(keyword, &textlist_keywords[0])) {
  590.         case TEXTLIST_ITEM_TYPE_TEXT :
  591.            status = add_template_text_list_entry(new_template, arg);
  592.            break;
  593.      }
  594.      break;
  595.  
  596.       case BLOCK_TYPE_BORDERDATA :
  597.  
  598.      /* Read border data */
  599.      bd = &new_template->tp_Data.tp_BorderData;
  600.      switch (search_keyword(keyword, &borderdata_keywords[0])) {
  601.         case BORDERDATA_ITEM_TYPE_TYPE :
  602.            bd->bd_Type = Atol(arg);
  603.            break;
  604.      }
  605.      break;
  606.  
  607.       case BLOCK_TYPE_TEXTDATA :
  608.  
  609.      /* Read text data */
  610.      td = &new_template->tp_Data.tp_TextData;
  611.      switch (search_keyword(keyword, &textdata_keywords[0])) {
  612.         case TEXTDATA_ITEM_TYPE_TYPE :
  613.            td->td_Type = Atol(arg);
  614.            break;
  615.  
  616.         case TEXTDATA_ITEM_TYPE_FLAGS :
  617.            td->td_Flags = Atol(arg);
  618.            break;
  619.  
  620.         case TEXTDATA_ITEM_TYPE_TEXT :
  621.            if (td->td_Type == TEXT_DATA_TYPE_TEXT) {
  622.           status = duplicate_string(arg, &td->td_Text);
  623.            } else {
  624.           td->td_Text = (BYTE *)Atol(arg);
  625.            }
  626.            break;
  627.  
  628.         case TEXTDATA_ITEM_TYPE_TEXTATTR :
  629.            if (!(td->td_TextAttr = open_template_font_by_num(tl,
  630.                               (USHORT)Atol(arg)))) {
  631.           status = EDITOR_ERROR_INVALID_FONT;
  632.            }
  633.            break;
  634.      }
  635.      break;
  636.  
  637.       case BLOCK_TYPE_GADGETDATA :
  638.  
  639.      /* Read gadget data */
  640.      tp = new_template;
  641.      gd = &tp->tp_Data.tp_GadgetData;
  642.      switch (search_keyword(keyword, &gadgetdata_keywords[0])) {
  643.         case GADGETDATA_ITEM_TYPE_TYPE :
  644.            gd->gd_Type = Atol(arg);
  645.            break;
  646.  
  647.         case GADGETDATA_ITEM_TYPE_FLAGS :
  648.            gd->gd_Flags = Atol(arg);
  649.            break;
  650.  
  651.         case GADGETDATA_ITEM_TYPE_TEXT :
  652.            if (*arg == '0') {
  653.           gd->gd_Text = NULL;
  654.            } else {
  655.           status = duplicate_string(arg, &gd->gd_Text);
  656.            }
  657.            break;
  658.  
  659.         case GADGETDATA_ITEM_TYPE_TEXTATTR :
  660.            if (!(gd->gd_TextAttr = open_template_font_by_num(tl,
  661.                               (USHORT)Atol(arg)))) {
  662.           status = EDITOR_ERROR_INVALID_FONT;
  663.            }
  664.            break;
  665.  
  666.         case GADGETDATA_ITEM_TYPE_SPECIAL1 :
  667.            gd->gd_SpecialData.gd_Data.gd_Data1 = Atol(arg);
  668.            break;
  669.  
  670.         case GADGETDATA_ITEM_TYPE_SPECIAL2 :
  671.            gd->gd_SpecialData.gd_Data.gd_Data2 = Atol(arg);
  672.            break;
  673.  
  674.         case GADGETDATA_ITEM_TYPE_SPECIAL3 :
  675.            switch (gd->gd_Type) {
  676.           case GADGET_DATA_TYPE_BUTTON :
  677.           case GADGET_DATA_TYPE_CHECK :
  678.           case GADGET_DATA_TYPE_INTEGER :
  679.           case GADGET_DATA_TYPE_SLIDER :
  680.           case GADGET_DATA_TYPE_SCROLLER :
  681.           case GADGET_DATA_TYPE_COUNT :
  682.           case GADGET_DATA_TYPE_PALETTE :
  683.              gd->gd_SpecialData.gd_Data.gd_Data3 = (VOID *)Atol(arg);
  684.              break;
  685.           case GADGET_DATA_TYPE_STRING :
  686.              status = duplicate_string(arg,
  687.                  (BYTE **)&gd->gd_SpecialData.gd_Data.gd_Data3);
  688.              break;
  689.           case GADGET_DATA_TYPE_MX :
  690.           case GADGET_DATA_TYPE_CYCLE :
  691.              status = build_template_text_array(tp);
  692.              break;
  693.           case GADGET_DATA_TYPE_LISTVIEW :
  694.              gd->gd_SpecialData.gd_ListViewData.gd_ListViewList = &tp->tp_TextList;
  695.              break;
  696.            }
  697.            break;
  698.      }
  699.      break;
  700.    }
  701.    return(status);
  702. }
  703.     /* Search keyword in given list */
  704.  
  705.    STATIC USHORT
  706. search_keyword(BYTE *keyword, BYTE **keyword_list)
  707. {
  708.    BYTE   *word;
  709.    USHORT count = 0, num = 0;
  710.  
  711.    while (word = *keyword_list++) {
  712.       count++;
  713.       if (!Strcmp(word, keyword)) {
  714.      num = count;
  715.      break;
  716.       }
  717.    }
  718.    return(num);
  719. }
  720.